package com.bkhech.controller;


import cn.hutool.core.util.StrUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import com.bkhech.api.feign.UserFein;
import com.bkhech.excptions.GraceException;
import com.bkhech.grace.result.GraceJSONResult;
import com.bkhech.grace.result.ResponseStatusEnum;
import com.bkhech.pojo.vo.UsersVO;
import com.bkhech.pojo.vo.VideoMsgVO;
import com.bkhech.service.FileService;
import com.bkhech.utils.JcodecVideoUtil;
import com.bkhech.utils.JsonUtils;
import com.bkhech.utils.QrCodeUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/file")
@Slf4j
public class FileController {

    @Resource
    private FileService fileService;

    @Resource
    private UserFein userFein;

    @PostMapping("/uploadFaceTest")
    public GraceJSONResult<Void> hello1(String userId, MultipartFile file) throws Exception {
        String filename = file.getOriginalFilename();

        String fileSuffix = filename.substring(filename.lastIndexOf(StrUtil.DOT));
        String newFileName = userId + fileSuffix;


        String rootPath = "D:\\upload";
        String filePath = rootPath + File.separator + "face" + File.separator + newFileName;

        File newFile = new File(filePath);
        if (!newFile.getParentFile().exists()) {
            newFile.getParentFile().mkdirs();
        }

        file.transferTo(newFile);

        return GraceJSONResult.ok();
    }


    @PostMapping("/uploadFace")
    public GraceJSONResult<UsersVO> uploadFace(String userId, MultipartFile file) {
        log.info("用户id: {}", userId);
        if (StrUtil.isBlank(userId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        String filename = file.getOriginalFilename();
        if (StrUtil.isBlank(filename)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }
        // 重新修改文件名
        filename = "face" + StrUtil.SLASH + userId + StrUtil.SLASH + filename; // 对的写法
        // filename = "face" + File.separator + userId + File.separator + filename; // 错误的写法
        String url = fileService.uploadFileAndReturnUrl(filename, file);
        // 微服务保存新的用户头像地址
        GraceJSONResult<UsersVO> result = userFein.updateFace(userId, url);
        if (result.getSuccess()) {
            UsersVO data = result.getData();
            return GraceJSONResult.ok(data);
        }
        return GraceJSONResult.ok();
    }

    @PostMapping("/generatorQrCode")
    public GraceJSONResult<String> generatorQrCode(String wechatNumber, String userId) {
        Map<String, String> data = new HashMap<>(4) {{
            put("wechatNumber", wechatNumber);
            put("userId", userId);
        }};
        String objectToJson = JsonUtils.objectToJson(data);
        // todo 到时候上线的时候filepath地址要换一下
        String qrCodePath = QrCodeUtils.generateQRCode(objectToJson, 300, 300, "D:\\upload\\" + wechatNumber + ".png");
        if (StrUtil.isNotBlank(qrCodePath)) {
            String uuid = UUID.randomUUID().toString();
            String objectName = "wechatNumber" + StrUtil.SLASH + userId + StrUtil.SLASH + uuid + ".png";
            String imageQrCodeUrl = fileService.uploadFile(objectName, qrCodePath, true);
            return GraceJSONResult.ok(imageQrCodeUrl);
        }

        return GraceJSONResult.errorMsg("生成二维码失败");
    }

    @PostMapping("/uploadFriendCircleBg")
    public GraceJSONResult<UsersVO> uploadFriendCircleBg(MultipartFile file, String userId) {
        log.info("用户id:{}", userId);
        if (StrUtil.isBlank(userId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        String filename = file.getOriginalFilename();
        if (StrUtil.isBlank(filename)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }
        // 重新修改文件名
        filename = "friendCircleBg" + StrUtil.SLASH + userId + StrUtil.SLASH + this.dealWithoutFilename(filename); // 对的写法
        // filename = "face" + File.separator + userId + File.separator + filename; // 错误的写法
        String url = fileService.uploadFileAndReturnUrl(filename, file);
        // 微服务保存朋友圈地址
        GraceJSONResult<UsersVO> result = userFein.uploadFriendCircleBg(userId, url);
        if (result.getSuccess()) {
            UsersVO data = result.getData();
            return GraceJSONResult.ok(data);
        }
        return GraceJSONResult.ok();
    }

    @PostMapping("/uploadChatBg")
    public GraceJSONResult<UsersVO> uploadChatBg(MultipartFile file, String userId) {
        log.info("用户id:{}", userId);
        if (StrUtil.isBlank(userId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        String filename = file.getOriginalFilename();
        if (StrUtil.isBlank(filename)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }
        // 重新修改文件名
        filename = "chatBg" + StrUtil.SLASH + userId + StrUtil.SLASH + this.dealWithoutFilename(filename); // 对的写法
        // filename = "face" + File.separator + userId + File.separator + filename; // 错误的写法
        String url = fileService.uploadFileAndReturnUrl(filename, file);
        // 微服务保存朋友圈地址
        GraceJSONResult<UsersVO> result = userFein.uploadChatBg(userId, url);
        if (result.getSuccess()) {
            UsersVO data = result.getData();
            return GraceJSONResult.ok(data);
        }
        return GraceJSONResult.ok();
    }


    @PostMapping("/uploadFriendCircleImage")
    public GraceJSONResult<String> uploadFriendCircleImage(MultipartFile file, String userId) {
        log.info("用户id:{}", userId);
        if (StrUtil.isBlank(userId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        String filename = file.getOriginalFilename();
        if (StrUtil.isBlank(filename)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }
        // 重新修改文件名
        filename = "friendCircleImage" + StrUtil.SLASH + userId + StrUtil.SLASH + this.dealWithoutFilename(filename); // 对的写法
        // filename = "face" + File.separator + userId + File.separator + filename; // 错误的写法
        String url = fileService.uploadFileAndReturnUrl(filename, file);
        return GraceJSONResult.ok(url);
    }


    @PostMapping("/uploadChatPhoto")
    public GraceJSONResult<String> uploadChatPhoto(MultipartFile file, String userId) {
        String url = this.uploadForChatFiles(file, userId, "photo");
        return GraceJSONResult.ok(url);
    }

    @PostMapping("/uploadChatVideo")
    public GraceJSONResult<VideoMsgVO> uploadChatVideo(MultipartFile file, String userId) {
        String videoUrl = this.uploadForChatFiles(file, userId, "video");
        // 获取视频封面第一帧
        String coverName = UUID.randomUUID() + ".jpg";
        String coverPath = JcodecVideoUtil.videoFramesPath + StrUtil.SLASH + coverName;
        File coverFile = new File(coverPath);
        if (!coverFile.getParentFile().exists()) {
            coverFile.getParentFile().mkdirs();
        }
        try {
            JcodecVideoUtil.fetchFrame(file, coverFile);
            String coverUrl = fileService.uploadFile("cover" + StrUtil.SLASH + coverName, new FileInputStream(coverPath), true);
            VideoMsgVO videoMsgVO = new VideoMsgVO(videoUrl, coverUrl);
            return GraceJSONResult.ok(videoMsgVO);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
//        return GraceJSONResult.ok(videoUrl);
    }

    @PostMapping("/uploadChatVoice")
    public GraceJSONResult<String> uploadChatVoice(MultipartFile file, String userId) {
        String url = this.uploadForChatFiles(file, userId, "voice");
        return GraceJSONResult.ok(url);
    }


    private String uploadForChatFiles(MultipartFile file, String userId, String msgFileDir) {
        log.info("用户id:{}", userId);
        if (StrUtil.isBlank(userId)) {
            GraceException.display(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        String filename = file.getOriginalFilename();
        if (StrUtil.isBlank(filename)) {
            GraceException.display(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }
        filename = "chat" + StrUtil.SLASH + userId + StrUtil.SLASH + msgFileDir + StrUtil.SLASH + this.dealWithoutFilename(filename); // 对的写法
        return fileService.uploadFileAndReturnUrl(filename, file);
    }


    private String dealWithFilename(String filename) {
        String fileSuffix = filename.substring(filename.lastIndexOf(StrUtil.DOT));
        String newFileName = filename.substring(0, filename.lastIndexOf(StrUtil.DOT));
        String uuid = UUID.randomUUID().toString();
        return newFileName + StrUtil.DASHED + uuid + fileSuffix;
    }

    private String dealWithoutFilename(String filename) {
        String fileSuffix = filename.substring(filename.lastIndexOf(StrUtil.DOT));
        String uuid = UUID.randomUUID().toString();
        return uuid + fileSuffix;
    }
}
